/*
	Test noise rendering.
*/

#include "Tests.h"

#ifdef _NOISE_UNIT_TEST

Source CreateSource()
{
	const float	src0_const = 1.0f;

	// src0
	Source src0 = nCreateSource( CONSTANT );
	CHECK_N( nSetArgFloat( src0, ARG_CONST, &src0_const, 1 ) );

	// src1
	Source src1 = nCreateSource( BILLOW );

	// src2
	float points[4*2] = {	0.1f, 0.5f,
							0.2f, 13.1f,
							0.4f, 5.8f,
							0.8f, 9.1f };
	Source src2 = nCreateSource( CURVE );
	CHECK_N( nSetArgSource( src2, SOURCE_0, src1 ) );
	CHECK_N( nSetArgFloat( src2, ARG_ADD_CONTROL_POINTS, points, count_of(points) ) );

	// src3
	Source src3 = nCreateSource( ADD );
	CHECK_N( nSetArgSource( src3, SOURCE_0, src0 ) );
	CHECK_N( nSetArgSource( src3, SOURCE_1, src2 ) );

	// src4
	Source src4 = nCreateSource( CYLINDERS );
	
	// src5
	Source src5 = nCreateSource( PERLIN );

	// src6
	Source src6 = nCreateSource( RIDGED_MULTI );

	// src7
	Source src7 = nCreateSource( SELECT );
	CHECK_N( nSetArgSource( src7, SOURCE_0, src4 ) );
	CHECK_N( nSetArgSource( src7, SOURCE_1, src5 ) );
	CHECK_N( nSetArgSource( src7, SOURCE_2, src6 ) );

	// src8
	Source src8 = nCreateSource( TERRACE );
	CHECK_N( nSetArgSource( src8, SOURCE_0, src7 ) );
	CHECK_N( nSetArgFloat( src8, ARG_ADD_CONTROL_POINTS, points, count_of(points) ) );

	// src9
	Source src9 = nCreateSource( TURBULENCE );
	CHECK_N( nSetArgSource( src9, SOURCE_0, src8 ) );

	// src10
	Source src10 = nCreateSource( VORONOI );
	
	// src11
	Source src11 = nCreateSource( MUL );
	CHECK_N( nSetArgSource( src11, SOURCE_0, src9 ) );
	CHECK_N( nSetArgSource( src11, SOURCE_1, src10 ) );

	return src11;
}


void RenderCLTest()
{
}


void RenderMemTest()
{
	Source src_last = CreateSource();

	EProgram prog_type =
		//*
			OPENCL_PROGRAM;
		/*/
			NATIVE_PROGRAM;
		//*/

	// prog
	Program prog = nCreateProgram( prog_type );
	CHECK_N( nBuildProgram( prog, src_last, EBuildOptions( DEFAULT_OPTIONS ) ) );

	int show_preview = true;
	CHECK_N( nSetProgramInteger( prog, SHOW_IMAGE_PREVIEW, &show_preview, 1 ) );

	const uvec2		size( 128, 128 );
	buffer<float>	data( size.Square() );
	CHECK_N( nRenderToMemory( prog, size.x, size.y, 0, 0, 0, R, FLOAT32, data.ptr() ) );

	string	str("Program result:\n");

	for (uint y = 0; y < size.y; ++y)
	{
		for (uint x = 0; x < size.x; ++x)
		{
			str << data[ size.x * y + x ] << ", ";
		}
		str << "\n";
	}
	LOG( str.cstr(), e_log_msg::DEBUG );

	nDeleteProgram( prog );
}


void RenderGLTest()
{
	using namespace GLShell;

	class CWindowUpdater : public IWindowUpdater, public IWindowEventListener
	{
	protected:
		GLTexture2D		tex;
		GLProgram		prog;
		bool			resized;
		bool			inited;

	public:
		CWindowUpdater (): resized(true), inited(false) {}

		void OnUpdate(CWindow *pWnd)
		{
			if ( resized )
			{
				SMAN()->Viewport( irect( ivec2(0), pWnd->Descriptor().vSize.To<ivec2>() ) );
				resized = false;
			}

			if ( not inited )
			{
				OnInit();
				inited = true;
			}

			glClear( GL_COLOR_BUFFER_BIT );

			((GLWindow *)pWnd)->SwapBuffers();
		}

		void OnInit ()
		{
			tex.Create( gl_tex_iformat::R32F, uvec3(1024,768,0) );


		}

		void ProcessMessage(const TWindowEvent &sEvent)
		{
			if ( sEvent.eEventType == e_wnd_event::MESSAGE )
			{
				if ( sEvent.sEvent.sMsg.eMsg == TWindowEvent::TMessage::RESIZE ||
					 sEvent.sEvent.sMsg.eMsg == TWindowEvent::TMessage::MAXIMIZED )
				{
					resized = true;
				}
			}
		}
	};



	Source src_last = CreateSource();
	
	EProgram prog_type = OPENCL_PROGRAM;
	
	// prog
	Program prog = nCreateProgram( prog_type );
	CHECK_N( nBuildProgram( prog, src_last, EBuildOptions( DEFAULT_OPTIONS ) ) );

	int show_preview = true;
	CHECK_N( nSetProgramInteger( prog, SHOW_IMAGE_PREVIEW, &show_preview, 1 ) );


	GLWindow			wnd;
	GLDefaultRender		render;
	CWindowUpdater		updater;

	wnd.CreateGL( GLWindow::TDescriptorExt( CWindow::TDescriptor( uvec2(1024,768), ivec2(), e_wnd_style::DEF_WINDOWED ),
					GLWindow::TGLDescriptor( e_glinit_flags::DEFAULT, 32 ), true ),
					"Render to OpenGL texture test window" );
		
	wnd.AddUpdater( &updater );
	
	render.Init( &wnd );

	{
		wnd.Show();
		wnd.Loop();
	
		wnd.MakeCurrent();
	}

	render.Destroy();
	wnd.Destroy();
}


void RenderFileTest()
{
}

#endif	// _NOISE_UNIT_TEST